home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PACKET
/
PMPSRC11.ZIP
/
LEVEL1RX.C
< prev
next >
Wrap
Text File
|
1991-07-30
|
5KB
|
198 lines
/*
level1rx.c -- Level 1 synchronous receive routines
Poor Man's Packet (PMP)
Copyright (c) 1991 by Andrew C. Payne All Rights Reserved.
Permission to use, copy, modify, and distribute this software and its
documentation without fee for NON-COMMERCIAL AMATEUR RADIO USE ONLY is hereby
granted, provided that the above copyright notice appear in all copies.
The author makes no representations about the suitability of this software
for any purpose. It is provided "as is" without express or implied warranty.
July, 1989
Andrew C. Payne
*/
/* ----- Includes ----- */
#include <stdio.h>
#include <alloc.h>
#include <conio.h>
#include <dos.h>
#include "pmp.h"
#include "ports.h"
#define MAXRXQUEUE 20 /* max items in queue */
#define MAXL1DSIZE 400 /* max size of level 1 data field */
extern word timer(void);
extern word waittrans(word from);
/* ---- Local Variables ----- */
static struct ax25_level1 *RXQueue[MAXRXQUEUE]; /* Receive queue */
static int RXQSize; /* number of items in queue */
/* ----- Subroutines ----- */
/* RXCarrier()
Returns TRUE if receive carrier detected.
*/
int RXCarrier()
{
register byte x;
x = inportb(CDPort) & CDBit;
return CDLevel ? x : !x;
}
/* RXLevel1()
Called whenever a RX carrier is detected, handles packet reception.
Received packets are put in the receive queue.
Returns the number of packets in the RXQueue.
*/
int RXLevel1(void)
{
int j;
word t1,t2; /* transition times */
int gotsync; /* TRUE if we have gotten a flag */
int bits; /* bit time */
byte *p; /* pointer to RX buffer */
byte c; /* current rec'd character */
int b; /* bits in c */
struct ax25_level1 *RXB; /* current RX buffer */
int bitcount; /* count of bits received */
t1 = timer(); /* current time */
gotsync = FALSE; /* we have no flag */
ShowTXRX(FALSE,TRUE); /* update screen status */
bitcount = 0; /* start counting bits */
disable(); /* no interruptions */
restart:
if(RXQSize >= MAXRXQUEUE) { /* is the RX Queue full? */
RXQOverflow++; /* count overflows */
enable(); /* re-enable interrupts */
return RXQSize; /* abort */
}
RXB = RXQueue[RXQSize]; /* next queue entry */
p = RXB->data; /* initialize */
b = c = 0;
while(RXCarrier()) {
/* wait for next transition */
t2 = waittrans(t1-20000);
bits = (((t1 - t2) + 994) / BITTIME) - 1;
bitcount += (bits + 1);
t1 = t2;
/* check for SYNC character */
if(bits == 6) {
/* if we've already got a sync, check for an incoming packet */
if(gotsync) {
if(p != RXB->data) {
if(b == 1) { /* got one! */
RXB->len = p - RXB->data;
RXQSize++; /* add item */
goto restart; /* do again */
} else
RXFrameErr++;
}
}
gotsync = TRUE;
b = c = 0;
/* store bits in the incoming packet */
} else if(bits >= 0 && bits < 6) {
j = bits; /* store the bits in C */
while(j--) {
c >>= 1;
b++;
c |= 0x80;
if(b == 8) {
*p++ = c; /* store it */
c = 0;
b = 0;
}
}
if(bits != 5) {
c >>= 1;
b++;
if(b == 8) {
*p++ = c; /* store it */
c = 0;
b = 0;
}
}
} else /* some strange bit count */
gotsync = FALSE;
/* check for RX buffer overflow */
if((p - RXB->data) > MAXL1DSIZE) { /* packet too long */
RXBOverflow++;
gotsync = FALSE;
goto restart;
}
}
/* lost carrier */
enable(); /* interrupts allowed */
ShowTXRX(FALSE,FALSE);
ClockAdjust(bitcount); /* speed up clock */
return RXQSize;
}
/* RXProcess()
Processes the packets sitting in the level1 RX queue. Valid
packets are handed up to the AX.25 routines.
*/
void RXProcess(void)
{
int i;
/* empty RX queue? */
if(RXQSize == 0)
return;
/* process RXQueue items */
for(i=0; i<RXQSize; i++) {
/* if CRC is good, show & handle packet */
if(CRCCheck(RXQueue[i])) {
RXCount++;
AX25Level2(RXQueue[i]); /* upcall */
} else {
RXCRCErr++;
if(PassMode) {
uprintf(BrightAttr,"~");
AX25Level2(RXQueue[i]); /* upcall */
}
}
}
/* empty RX Queue */
RXQSize = 0;
}
/* RXInit()
Initialize the RX routines: allocate the level 1 receive buffers.
*/
void RXInit()
{
int i;
/* allocate the RX Queue */
for(i=0; i<MAXRXQUEUE; i++) {
if((RXQueue[i] = malloc(sizeof(struct ax25_level1) + MAXL1DSIZE))
== NULL)
OutOfMemory();
}
RXQSize = 0; /* empty queue */
}